package com.gitee.wsl.platform.concurrent

import kotlinx.coroutines.CloseableCoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.newFixedThreadPoolContext
import kotlinx.coroutines.newSingleThreadContext
import platform.posix.pthread_self
import platform.posix.pthread_t
import platform.posix.usleep
import kotlin.coroutines.CoroutineContext

//internal actual class InternalThreadId(private val pthread: pthread_t) {
//    override fun equals(other: Any?): Boolean {
//        return this === other || (other is InternalThreadId && pthread == other.pthread)
//    }
//
//    override fun hashCode() = pthread.hashCode()
//    override fun toString() = pthread.toString()
//}
//
//internal actual class InternalThread {
//    actual companion object {
//        @Suppress("UNNECESSARY_NOT_NULL_ASSERTION") // Assertion needed when compiling on Mac
//        actual fun getId(): InternalThreadId = InternalThreadId(pthread_self()!!)
//
//        actual fun sleepMs(millis: Int) {
//            usleep((millis * 1000).toUInt())
//        }
//    }
//}

/**
 * Runs the provided [block] on the main thread
 * @param block the code to run on the main thread.
 */
actual fun runOnMain(block: () -> Unit) {
    block()
}

/**
 * Creates a coroutine execution context using a single thread.
 *
 * **NOTE: The resulting [CloseableCoroutineDispatcher] owns native resources (its thread).
 * Resources are reclaimed by [CloseableCoroutineDispatcher.close].**
 * @param name The name of the thread to be created.
 */
@OptIn(ExperimentalCoroutinesApi::class, DelicateCoroutinesApi::class)
actual fun singleThreadDispatcher(name: String): CloseableCoroutineDispatcher = newSingleThreadContext(name)

/**
 * Creates a coroutine execution context using a thread pool.
 *
 * **NOTE: The resulting [CloseableCoroutineDispatcher] owns native resources (its thread).
 * Resources are reclaimed by [CloseableCoroutineDispatcher.close].**
 */
@OptIn(ExperimentalCoroutinesApi::class, DelicateCoroutinesApi::class)
actual fun threadPoolDispatcher(numberOfThreads: UInt, name: String): CloseableCoroutineDispatcher = newFixedThreadPoolContext(numberOfThreads.toInt(), name)



/** Native `runBlocking` implementation */
actual fun <T> runBlocking(
    context: CoroutineContext,
    block: suspend CoroutineScope.() -> T,
): T = kotlinx.coroutines.runBlocking(context, block)
